/*
 * Quote.java
 *
 * Copyright (C) 2003-2007 tick-TS AG, All Rights Reserved
 *
 */

package de.tbmx.api;

import java.util.*;
import java.util.regex.*;

public class Quote 
{
	public String getISIN()
	{
		return isin;
	}
	public String getExchange()
	{
		return exchange;
	}
	public String getSymbol()
	{
		return symbol;
	}
	public double getLast()
	{
		return last;
	}
	public double getBid()
	{
		return bid;
	}
	public double getAsk()
	{
		return ask;
	}
	public int getLastSize()
	{
		return lastsize;
	}
	public int getAskSize()
	{
		return asksize;
	}
	public int getBidSize()
	{
		return bidsize;
	}
	public String getName()
	{
		return name;
	}
	
	public String getPhase()
	{
		return phase;
	}
	
	public String getCurrency()
	{
		return curr;
	}
	
	@Override
	public String toString()
	{
		return "[TBQ:"+isin+"."+exchange+"("+symbol+")]";
	}
	
	public double getStep()
	{
		return m_step;
	}
	
	public String getTime()
	{
		return time;
	}
	public void setStep(double s)
	{
		m_step = s;
	}
	
	/* Here be dragons */
	String isin;
	String exchange;
	String symbol;
	String name;
	String phase;
	String curr;
	String time;
	double m_step = 0;
	
	double last, bid, ask;
	int lastsize, bidsize, asksize;
	
	double[] l2bid, l2ask;
	int[] l2bidsize, l2asksize;
	
	/* Listener support */
	Set<QuoteListener> listeners=new HashSet<QuoteListener>();
	Set<QuoteListener> l2Listeners=new HashSet<QuoteListener>();
	
	private Pattern symbPattern=Pattern.compile("[a-zA-Z][a-zA-Z].{9}\\d");

	Quote(String isin, String exchange)
	{
		if(symbPattern.matcher(isin).matches())
			this.isin=isin;
		else
			this.symbol=isin;
		
		this.exchange=exchange;
		l2bid = new double[10];
		l2ask = new double[10];
		l2bidsize = new int[10];
		l2asksize = new int[10];
	}
	
	synchronized void addListener(QuoteListener ql, boolean level2)
	{
		if (level2)
			l2Listeners.add(ql);
		listeners.add(ql);
	}
	
	// Removes the QuoteListener (whether level1 or level2) and returns true if it was a level2 listener
	synchronized boolean removeListener(QuoteListener ql)
	{
		listeners.remove(ql);
		return l2Listeners.remove(ql); 
	}
	
	/**
	 * @param what
	 */
	void fireChanged(int what, int level)
	{
		QuoteListener ql[] = null;
		synchronized(this)
		{
			if (level==0)
				ql=listeners.toArray(new QuoteListener[listeners.size()]);
			else
				ql=l2Listeners.toArray(new QuoteListener[l2Listeners.size()]);
		}
		for(int c=0;c<ql.length;c++)
			ql[c].quoteChanged(this,what,level);
	}
	
	String getSubscriptionString(boolean subscribe, boolean level2)
	{
		String mode;
		if (level2)
			mode="L2";
		else
			mode="L1";
		if (subscribe)
			mode=mode+"INC";
		else
			mode=mode+"DEC";
		if(isin!=null)
			return "QTS|ISIN="+isin+"|MODE="+mode+"|EXCHANGE="+exchange;
		return "QTS|SYMBOL="+symbol+"|MODE="+mode+"|EXCHANGE="+exchange;
	}
	
	synchronized int getL1Count()
	{
		return listeners.size();
	}
	
	synchronized int getL2Count()
	{
		return l2Listeners.size();
	}
}
